<template>
  <div>
    <el-input type="textarea" :rows="5" v-model="accessToken"/>
    <el-button @click="initSocket">连接</el-button>
    <el-button @click="leaveRoom">离开房间</el-button>
  </div>
</template>

<script>
import io from "socket.io-client";
import {markRaw} from "vue";
import {encrypt} from "@/utils/jsencrypt";
import {getRyToken} from "@/api/core/ry";
import {getConfigKey} from "@/api/system/config";
import {device} from "@rongcloud/plugin-rtc";

export default {
  name: "test",
  data() {
    return {
      accessToken: '',
      socket: null,
      imClient: null,
      rtcClient: null,
      rtcRoom: null,
      microphoneDeviceId: '',
      cameraDeviceId: ''
    }
  },
  created() {
    this.accessToken = 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImZlN2JjYzBjLThmMTItNDE2OC05ZTU4LWRmOGM3OWFmM2I1YSJ9._vKz7KzMmqM_kZOitfLUkSv72RMA3NX2MemiYncQvAMPSyhM6DHqCrsjdinPJTJFVrEkc_jFYYBgGB28fkpznw'
    localStorage.setItem('access_token', this.accessToken)

    device.getMicrophones().then(res => {
      const microphones = res
      if (microphones.length > 0) {
        this.microphoneDeviceId = microphones[0].deviceId
      }
    })

    device.getCameras().then(res => {
      const cameras = res
      if (cameras.length > 0) {
        this.cameraDeviceId = cameras[0].deviceId
      }
      console.log(this.cameraDeviceId)
    })
  },
  methods: {
    initSocket() {
      this.connection = markRaw(io( {
        path: `${import.meta.env.VITE_APP_WS_API}/socket`,
        transports: ['websocket'],
        query: {
          accessToken: this.accessToken
        },
        autoConnect: false
      }))

      this.connection.on('invite', data => {
        this.connection.emit('answer', data)
      })
      this.connection.on('complete', data => {
        this.joinRoom(data.meetRecordId)
      })

      this.connection.connect()
      this.initRTC()
    },
    async initRTC() {
      const ryRes = await getRyToken()
      const ryToken = ryRes.data

      const appKeyRes = await getConfigKey('ry.appKey')
      const appKey = appKeyRes.data

      const naviRes = await getConfigKey('ry.navi')
      const navi = naviRes.data

      RongIMClient.init(appKey, null, {
        navi,
        logLevel: import.meta.env.PROD ? 3 : 0
      })

      this.imClient = markRaw(RongIMClient)

      if (!this.imClient) {
        console.log('IM尚未初始化')
        return
      }

      const vm = this
      await this.imClient.connect(ryToken, {
        onSuccess: function (userId) {
          console.log(`IM连接成功`)
          vm.$modal.msgSuccess('IM连接成功')
          vm.initRTCClient()
        },
        onTokenIncorrect: function () {
          console.log(`IM连接失败, 失败原因: token 无效`)
        },
        onError: function (errorCode) {
          console.log(`IM连接失败，错误码:${errorCode}`)
        },
      })
    },
    initRTCClient() {
      this.rtcClient = markRaw(RongIMClient.getInstance().install(RCRTC.installer, {
        timeout: 30000,
        logLevel: import.meta.env.PROD ? RCEngine.LogLevel.INFO : RCEngine.LogLevel.DEBUG
      }))
      this.$modal.msgSuccess('rtcClient初始化完成')
    },
    async joinRoom(meetRecordId) {
      if (!this.rtcClient) {
        this.$modal.msgError('音视频服务未初始化，无法开启会议');
        return
      }

      const {code, room, tracks} = await this.rtcClient.joinRTCRoom(meetRecordId)
      console.log('12580',code, room, tracks);

      if (code !== RCRTC.RCRTCCode.SUCCESS) {
        this.$modal.msgError(`加入会议失败: ${code}`)
        return
      }

      this.rtcRoom = markRaw(room)

      await this.publishMicrophoneCamera()
    },
    async publishMicrophoneCamera() {
      if (!this.rtcClient || !this.rtcRoom) {
        this.$modal.msgError('音视频服务未初始化或未加入会议')
        return
      }

      const {code, tracks} = await this.rtcClient.createMicrophoneAndCameraTracks('RongCloudRTC', {
        audio: {
          micphoneId: this.microphoneDeviceId
        },
        video: {
          cameraId: this.cameraDeviceId,
          frameRate: 'FPS_30',
          resolution: 'W1920_H1080'
        }
      })
      if (code !== RCRTC.RCRTCCode.SUCCESS) {
        this.$modal.msgError(`获取麦克风或摄像头资源失败: ${code}`)
        return
      }

      await this.publish(tracks)
    },
    async publish(tracks) {
      if (!Array.isArray(tracks) || tracks.length === 0) {
        return
      }

      const {code} = await this.rtcRoom.publish(tracks)
      if (code === RCRTC.RCRTCCode.SUCCESS) {
        this.$modal.msgSuccess('发布资源成功')
      } else {
        this.$modal.msgError(`发布资源失败: ${code}`)
        return Promise.reject()
      }
    },
    async leaveRoom() {
      await this.rtcClient.leaveRoom(this.rtcRoom)
      this.$modal.msgSuccess('离开房间成功')
    }
  }
}
</script>

<style scoped>

</style>
